package com.lili.collection.jdbc.enums;

import cn.hutool.core.collection.CollUtil;

import java.util.Collections;
import java.util.List;

/**
 * @author lili
 * @description TODO
 * @date 2023/2/15 1:08
 */
public enum DatabaseVendor {
    DB2(
            CollUtil.newArrayList("jdbc:db2:", "jdbc:ibmdb:", "jdbc:ids:"),
            CollUtil.newArrayList("com.ibm.db2.jcc.DB2Driver"),
            Collections.emptyList()
    ),
    MYSQL(
            CollUtil.newArrayList("jdbc:mysql:"),
            CollUtil.newArrayList("com.mysql.cj.jdbc.Driver", "com.mysql.jdbc.Driver"),
            CollUtil.newArrayList(QuoteChar.NONE.getLabel(), QuoteChar.BACKTICK.getLabel())
    ),
    MARIADB(
            CollUtil.newArrayList("jdbc:mariadb:"),
            CollUtil.newArrayList("org.mariadb.jdbc.Driver"),
            Collections.emptyList()
    ),
    HIVE(
            CollUtil.newArrayList("jdbc:hive2:"),
            CollUtil.newArrayList("org.apache.hive.jdbc.HiveDriver", "com.cloudera.impala.jdbc41.Driver", "com.cloudera.impala.jdbc4.Driver"),
            Collections.emptyList()
    ),
    TERADATA(
            CollUtil.newArrayList("jdbc:teradata"),
            CollUtil.newArrayList("com.teradata.jdbc.TeraDriver"),
            Collections.emptyList()
    ),
    ORACLE(
            CollUtil.newArrayList("jdbc:oracle:"),
            CollUtil.newArrayList("oracle.jdbc.driver.OracleDriver", "oracle.jdbc.OracleDriver"),
            CollUtil.newArrayList(QuoteChar.DOUBLE_QUOTES.getLabel(), QuoteChar.NONE.getLabel())
    ),
    POSTGRESQL(
            CollUtil.newArrayList("jdbc:postgresql:"),
            CollUtil.newArrayList("org.postgresql.Driver"),
            CollUtil.newArrayList(QuoteChar.DOUBLE_QUOTES.getLabel(), QuoteChar.NONE.getLabel())
    ),
    SQL_SERVER(
            CollUtil.newArrayList("jdbc:sqlserver:"),
            CollUtil.newArrayList("com.microsoft.sqlserver.jdbc.SQLServerDriver"),
            CollUtil.newArrayList(QuoteChar.NONE.getLabel(), QuoteChar.DOUBLE_QUOTES.getLabel(), QuoteChar.SQUARE_BRACKETS.getLabel())
    ),
    VERTICA(
            CollUtil.newArrayList("jdbc:vertica:"),
            CollUtil.newArrayList("com.vertica.jdbc.Driver"),
            CollUtil.newArrayList(QuoteChar.NONE.getLabel(), QuoteChar.BACKTICK.getLabel())
    ),
    UNKNOWN(Collections.emptyList(), Collections.emptyList(), Collections.emptyList()),
    ;

    private final List<String> jdbcPrefixes;
    private final List<String> drivers;
    private final List<String> quoteCharacters;

    DatabaseVendor(List<String> jdbcPrefixes, List<String> drivers, List<String> quoteCharacters) {
        this.jdbcPrefixes = jdbcPrefixes;
        this.drivers = drivers;
        this.quoteCharacters = quoteCharacters;
    }

    public List<String> getDrivers() {
        return drivers;
    }

    public List<String> getJdbcPrefixes() {
        return jdbcPrefixes;
    }


    public boolean isOneOf(DatabaseVendor... vendors) {
        if (vendors == null) {
            return false;
        }
        for (DatabaseVendor v : vendors) {
            if (this == v) {
                return true;
            }
        }
        return false;
    }

    /**
     * Return database vendor for given URL.
     */
    public static DatabaseVendor forUrl(String url) {
        for (DatabaseVendor vendor : DatabaseVendor.values()) {
            for (String prefix : vendor.jdbcPrefixes) {
                if (url.startsWith(prefix)) {
                    return vendor;
                }
            }
        }
        return UNKNOWN;
    }

    /**
     * Check if the given quote character is in the list of valid characters for this vendor. If the list is empty,
     * return it as valid.
     */
    public boolean validQuoteCharacter(String quoteChar) {
        if (this.quoteCharacters.isEmpty()) {
            return true;
        }
        for (String qC : this.quoteCharacters) {
            if (qC.equals(quoteChar)) {
                return true;
            }
        }
        return false;
    }
}